#include <stdio.h>
// функція-ядро додавання двох векторів
__global__ void vectorAdd (float z, // power
		float* a, // input vector
		float* b) // output pow vector
{
int index = blockIdx.x*blockDim.x+threadIdx.x;
b[index]=powf(a[index],z);
}

int main(int argc, char ** argv)
{
int N=1024*1024, i;
//size_t size = sizeof(float)*N;
// оголошення 3-х векторів
// виділення пам’яті для 3-х векторів
// float* h_a = (float*)malloc(sizeof(float));
float h_z = 2.0f;
size_t sizeOfArray = N*sizeof(float);
float * h_a = (float*)malloc(sizeOfArray);
for(i=0;i<N;i++)
{
	h_a[i]=i;
//	printf("%f %f\n",h_a[i],h_z);
}
float * h_b = (float*)malloc(sizeOfArray);
float * d_a = NULL;
float * d_b = NULL;
cudaMalloc((void**)&d_a,sizeOfArray);
cudaMalloc((void**)&d_b,sizeOfArray);
cudaMemcpy(d_a,h_a,sizeOfArray,cudaMemcpyHostToDevice);
vectorAdd<<<dim3((N/512),1), dim3(512,1)>>>(h_z,d_a,d_b);
cudaMemcpy(h_b,d_b,sizeOfArray,cudaMemcpyDeviceToHost);
for(i=0;i<N;i++)
printf("h_a=%f result h_b=%f \n",h_a[i],h_b[i]);

cudaFree(d_a);
cudaFree(d_b);
free(h_a);
free(h_b);
/*
float* vecA = (float*)malloc(size);
float* vecB = (float*)malloc(size);
float* vecC = (float*)malloc(size);
// оголошення 3-х векторів
float* GPUvecA;
float* GPUvecB;
float* GPUvecC;

// виділення пам’яті для 3-х векторів на пристрої
cudaMalloc(a);
cudaMalloc(&GPUvecA, size);
cudaMalloc(&GPUvecB, size);
cudaMalloc(&GPUvecC, size);
// копіювання даних з пам’яті хосту в пам’ять пристрою
cudaMemcpy(GPUvecA,vecA,size,cudaMemcpyHostToDevice);
cudaMemcpy(GPUvecB,vecB,size,cudaMemcpyHostToDevice);
	for(i=0;i<N;i++)
	{
		vecA[i]=1.1f;
		vecB[i]=2.2f;
		vecC[i]=20.0f;
		printf("%f - %f - %f \n",vecA[i],vecB[i],vecC[i]);
	}
	int threadsPerBlock = 256;
	int blocksPerGrid = (N + threadsPerBlock-1)/threadsPerBlock;
vectorAdd<<<blocksPerGrid,threadsPerBlock>>>(GPUvecA,GPUvecB,GPUvecC);
//printf("hello CUDA \n");
	
	cudaMemcpy(vecC,GPUvecC,size,cudaMemcpyDeviceToHost);
for(i=0;i<N;i++)
{
printf("vecA[%d]=%f \n",i,vecA[i]);
printf("vecB[%d]=%f \n",i,vecB[i]);
printf("vecC[%d]=%f \n",i,vecC[i]);
}
	cudaFree(GPUvecA);
	cudaFree(GPUvecB);
	cudaFree(GPUvecC);
	
	free(vecA);
	free(vecB);
	free(vecC);

*/
return 0;
}
